<?php

class Engine_User_Account extends Engine_Model {

	
	public function init() {
		//
	}
	
	
	public function create($values) {
		
		$return = false;
		if ($this->validRegistration($values)) {

			try {
				$verification_code = $this->generateVerificationCode();
				
				// INSERT into CORE_USERS
				$data = array(	'user_username' 			=> $values['username'],
								'user_password' 			=> $this->auth->passwordTreatment($values['password']),
								'user_email' 				=> $values['useremail'],
								'user_firstname' 			=> $values['firstname'],
								'user_lastname' 			=> $values['lastname'],
								'user_verification_code'	=> $verification_code,
								'user_last_ip' 				=> $_SERVER['REMOTE_ADDR'],
								'user_update_date' 			=> engine_date(),
								'user_password_date'		=> engine_date(),
								'user_login_date'			=> engine_date(),
								'user_params' 				=> serialize(array())
				);
				$core_users = new Engine_Db_Table_CoreUsers();
				$user_id = $core_users->insert($data);

				try {
					// INSERT into ACL_USER_ROLES
					$data = array(	'user_role_user_id' => $user_id,
									'user_role_role_id' => 1000  		// Guest role
					);
					$acl_user_roles = new Engine_Db_Table_AclUserRoles();
					$acl_user_roles->insert($data);
			
					
				} catch (Exception $e) {
					// Failed to insert core_user_stats
					$entry = sprintf($this->translate->_('LOG_CAUGHT_EXCEPTION'), $this->translate->_('ERRORS_ACL_USER_ROLES_INSERT'), (__METHOD__.' '.__LINE__) );
					$this->log->err($entry);
					$this->_error = $this->translate->_('ERRORS_ACL_USER_ROLES_INSERT');
				}
			} catch (Exception $e) {
				// Failed to insert core_users
				$entry = sprintf($this->translate->_('LOG_CAUGHT_EXCEPTION'), $this->translate->_('ERRORS_USER_ACCOUNT_CORE_USERS'), (__METHOD__.' '.__LINE__) );
				$this->log->err($entry);
				$this->_error = $this->translate->_('ERRORS_USER_ACCOUNT_CORE_USERS');
			}
			

			// Authenticate the new user
			if (!$this->auth->authenticate($values)) {
				// Failed
				$this->_error = $this->translate->_('ERRORS_USER_ACCOUNT_AUTH_FAILURE');
			} else {
				
				// Log success
				$authRecord = $this->auth->authRecord();
				$entry = sprintf($this->translate->_('ENGINE_NEW_ACCOUNT'), $user_id, $authRecord->user_username, $authRecord->user_email, $_SERVER['REMOTE_ADDR']);
				$this->log->info($entry);
				
				// SUCCESS:  Return the email verification code
				$this->sendEmailVerification($verification_code);
				$return = true;
			}
		}
		return $return;
	}
	
	
	private function generateVerificationCode() {
		return md5(REQUEST_MTIME.SITE_SALT.uniqid().SITE_NAME);
	}
	
	
	public function sendEmailVerification($code = null) {
		if ($this->auth->isActive()) {
			$authRecord = $this->auth->authRecord();
			if ($code == null) {
				$code = $this->generateVerificationCode();
				
				// UPDATE table CORE_USERS with login data
				$authRecord = $this->authRecord();
				$core_user = new Engine_Db_Table_CoreUsers();
				$data = array('user_verification_code' => $code );
				$where = $table->getAdapter()->quoteInto('user_id = ?', $authRecord->user_id);
				$core_user->update($data, $where);
			}
			
			$link = Zend_Registry::get('baseUrl')."/user/register/verify/?code=$code";
			
			$coreConfig = Zend_Registry::get('Core_Config');
			try {
				$mail = new Engine_Mail();
				$mail->setFrom($coreConfig['smtp_sender_address'], $coreConfig['smtp_sender_name']);
				$mail->addTo($authRecord->user_email, ($authRecord->user_firstname . ' '.$authRecord->user_lastname));
				$mail->setSubject(SITE_NAME);
				$mail->setBodyText("This is the text of the mail.  $link");
				$mail->send();
				$entry = sprintf($this->translate->_("ENGINE_MAIL_SENT"), $authRecord->user_email);
				$this->log->info($entry);
			} catch (Exception $e) {
				$entry = sprintf($this->translate->_("LOG_EMAIL_EXCEPTION_FAILURE"), $authRecord->user_email);
				$this->log->err($entry);
				$entry = sprintf($this->translate->_("LOG_EMAIL_EXCEPTION_MESSAGE"), $e->getMessage());
				$this->log->err($entry);
			}
		}
	}
	
	
	protected function validRegistration($values) {
		$return = false;

		// Make sure username does not exist		
		$core_users = new Engine_Db_Table_CoreUsers();
		$select = $core_users->select();
		$select->where('user_username = ?', $values['username']);
		$results = $core_users->fetchRow($select);		
		if ($results) {
			$this->_error = $this->translate->_('ERRORS_USER_ACCOUNT_USERNAME_EXISTS');
			
		} else {
			// Make sure username is not blacklisted
			$core_blacklist = new Engine_Db_Table_CoreBlacklist();
			$select = $core_blacklist->select();
			$select->where("blacklist_type_id = 'blacklist_user' AND blacklist_value = ?", $values['username']);
			$results = $core_blacklist->fetchRow($select);
			if ($results) {
				$this->_error = $this->translate->_('ERRORS_USER_ACCOUNT_USERNAME_BLACKLIST');
				
			} else {
				if ($values['password'] != $values['verify_password']) {
					$this->_error = $this->translate->_('ERRORS_USER_ACCOUNT_PASSWORD_MISMATCH');
					
				} else {
					if ($values['useremail'] != $values['verify_email']) {
						$this->_error = $this->translate->_('ERRORS_USER_ACCOUNT_EMAIL_MISMATCH');

					} else {
						$valdate = new  Zend_Validate_EmailAddress();
						if (!$valdate->isValid($values['useremail'])) {
							$this->_error = $this->translate->_('ERRORS_USER_ACCOUNT_EMAIL_INVALID');

						} else {
							$select = $core_blacklist->select();
							$select->where("blacklist_type_id = 'blacklist_email' AND blacklist_value = ?", $values['useremail']);
							$results = $core_blacklist->fetchRow($select);
							if ($results) {
								$this->_error = sprintf($this->translate->_("ERRORS_USER_BLACKLIST_EMAIL"), $user_email);
								$entry = sprintf($this->translate->_("LOG_BLACKLIST_CREATE_EMAIL"), $user_email);
								$this->log->err($entry);	
							} else {
							
								// Passed all conditions
								$return = true;
							}
						}
					}
				}
			}
		}

		return $return;
	}
	
	
	public function validUsername($username = null) {
		$result = false;
		if (!$username == null) {
			$core_users = new Engine_Db_Table_CoreUsers();
			$select = $core_users->select();
			$select->where('user_username = ?', $username);
			$results = $core_users->fetchRow($select);
			if ($results) {
				$result = true;
			}
		}
		return $result;
	}
	
	
	public function logout() {	
		
		if ($this->auth->isActive()) {
			$user = $this->auth->authRecord();
			$format = $this->translate->_('LOG_LOGOFF');
			$entry = sprintf($format, $user->user_id, $user->user_username, $user->user_email, $_SERVER['REMOTE_ADDR']);
			$this->log->info($entry);
		
			$this->auth->destroyAuthSession();
		}
	}	
	
	public function login(array $values) {
		$result = false;
		define('AUTH_RESULT_INACTIVE', 100100);
		define('AUTH_RESULT_SUSPENDED', 100200);
		define('AUTH_RESULT_INVALID_LOGIN', 100300);
		define('AUTH_RESULT_SUCCESS', 100500);
		
		$auth = $this->auth->authenticate($values);
		if ($auth->getCode() == Zend_Auth_Result::SUCCESS) {
			
			$identity = $auth->getIdentity();
			$authRecord = $this->auth->authRecord();

			if ($authRecord->user_suspended) {
				$result = AUTH_RESULT_SUSPENDED;
				$this->logout();
			} elseif (!$authRecord->user_active) {
				$result = AUTH_RESULT_INACTIVE;
				$this->logout();
			} else {
				$result = AUTH_RESULT_SUCCESS;
			}

		} elseif ($auth->getCode() == Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND) {
			$result = AUTH_RESULT_INVALID_LOGIN;	
	 	} elseif ($auth->getCode() == Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID) {
	 		$result = AUTH_RESULT_INVALID_LOGIN;
	 	}
		
		return $result;
	}
	
	public function verifyCode($code) {
		$return = false;
		
		// SELECT user record 
		$core_users = new Engine_Db_Table_CoreUsers();
		$select  = $core_users->select()->where('user_verification_code = ?', $code);
		$row = $core_users->fetchRow($select);
		
		if ($row) {			
			try {
				// UPDATE verification code in CORE_USERS
				$data = array(	'user_verification_code' => '');
				$where = $core_users->getAdapter()->quoteInto('user_id = ?', $row['user_id']);
				$core_users->update($data, $where);
				
				try {
					// INSERT into ACL_USER_ROLES
					$data = array(	'user_role_user_id' => $row['user_id'],
									'user_role_role_id' => 1001  		// Member role
					);
					$acl_user_roles = new Engine_Db_Table_AclUserRoles();
					$acl_user_roles->insert($data);
					$return = true;
				} catch (Exception $e) {
					// FAILED to insert membership into ACL
				}				
				
			} catch (Exception $e) {
				// FAILED to update core_user record
			}
			
		} else {
			// FAILED to find verification code.
		}
		
		return $return;
	}
} 


?>